#include <xboot.h>
#define SIZE_START (0x00008000)
#define IH_MAGIC 0x27051956
#define IH_NMLEN (37)
typedef struct image1_header {
    uint32_t    ih_magic;   /* Image Header Magic Number    */
    uint32_t    ih_default[2];  
    uint32_t    ih_size;    /* Image Data Size          */
    uint32_t    ih_load;    /* Data	 Load  Address      */
    uint32_t    ih_ep;      /* Entry Point Address      */
    uint8_t     ih_name[IH_NMLEN];  /* Image Name   */
} image1_header_t;

static uint32_t image_header_buffer[512 / sizeof(uint32_t)];

uint32_t sys_jamp_add(void);

enum {
	BOOT_DEVICE_FEL,
	BOOT_DEVICE_SPINOR,
	BOOT_DEVICE_SPINAND,
	BOOT_DEVICE_SDCARD,
};

static int get_boot_device(void)
{
	uint8_t s = *((volatile uint8_t *)(0x00020000 + 0x28));

    if(s == 0x3)
		return BOOT_DEVICE_SPINOR;
	else if(s == 0x4)
		return BOOT_DEVICE_SPINAND;
	else if(s == 0x0)
		return BOOT_DEVICE_SDCARD;
	return BOOT_DEVICE_SPINOR;

}
int xboot_main(int argc, char * argv[])
{
	char fmt[32];
	int i;
	void (*jamp)(void) = 0;

	int d = get_boot_device();
	if(d == BOOT_DEVICE_SPINOR)
	{
	struct image1_header *uimg = (struct image1_header *)&image_header_buffer;

		sys_spinor_init();
		sys_spinor_read(SIZE_START, uimg, sizeof(struct image1_header));
		sys_spinor_exit();

		uimg->ih_magic = __swab32(uimg->ih_magic);
		uimg->ih_size = __swab32(uimg->ih_size);
		uimg->ih_load = __swab32(uimg->ih_load);
		uimg->ih_ep = __swab32(uimg->ih_ep);

		sys_uart_putc('S');
		sys_uart_putc('P');
		sys_uart_putc('L');
		sys_uart_putc(':');
		sys_uart_putc('A');
		sys_uart_putc('c');
		sys_uart_putc('h');
		sys_uart_putc('i');
		sys_uart_putc('n');
		sys_uart_putc('w');
		sys_uart_putc('o');
		sys_uart_putc('o');
		sys_uart_putc('\r');
		sys_uart_putc('\n');
		if (uimg->ih_magic == IH_MAGIC)
		{
			sys_spinor_init();
		    sys_spinor_read(SIZE_START+sizeof(struct image1_header), (void *)uimg->ih_load, uimg->ih_size);
		    sys_spinor_exit();

			jamp = (void *)uimg->ih_ep;
    			jamp();

		}
	}

	fmt[0] = 'B';
	fmt[1] = 'o';
	fmt[2] = 'o';
	fmt[3] = 't';
	fmt[4] = ' ';
	fmt[5] = 't';
	fmt[6] = 'o';
	fmt[7] = ' ';
	fmt[8] = 'F';
	fmt[9] = 'E';
	fmt[10] = 'L';
	fmt[11] = ' ';
	fmt[12] = 'm';
	fmt[13] = 'o';
	fmt[14] = 'd';
	fmt[15] = '!';
	fmt[16] = '\r';
	fmt[17] = '\n';
	fmt[18] = '\0';
	printk(fmt);
	return_to_fel();
	
	return 0;
}
